package beautiful.butterfly.server.socketserver;


import beautiful.butterfly.server.socketserver.marshalling.ClientHandler;
import beautiful.butterfly.server.socketserver.marshalling.MarshallingCodeCFactory;
import beautiful.butterfly.server.socketserver.pojo.Request;
import beautiful.butterfly.server.socketserver.pojo.Response;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CountDownLatch;


public class Client {
    private static final Logger log = LoggerFactory.getLogger(Client.class);

    public static void main(String[] args) throws Exception {
        int port = 8080;
        if (args != null && args.length > 0) {
            try {
                port = Integer.valueOf(args[0]);
            } catch (NumberFormatException e) {
                // 采用默认值
            }
        }
        Request request = new Request();
        request.setMainModuleId(1);
        request.setSubModuleId(1);
        request.setCreateTime(System.currentTimeMillis());
        request.setContent("ok");
        Response response = new Client().connect("127.0.0.1", port, request);
        System.out.println(response);
    }

    public static Response connect(String host, int port, final Request request) throws Exception {
        // 配置客户端NIO线程组
        final CountDownLatch countDownLatch = new CountDownLatch(1);
        final ClientHandler clientHandler = new ClientHandler(request, countDownLatch);
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel socketChannel)
                                throws Exception {

                            socketChannel.pipeline().addLast(
                                    MarshallingCodeCFactory
                                            .buildMarshallingDecoder());
                            socketChannel.pipeline().addLast(
                                    MarshallingCodeCFactory
                                            .buildMarshallingEncoder());
                            socketChannel.pipeline().addLast(clientHandler);

                        }
                    });

            // 发起异步连接操作
            ChannelFuture channelFuture = bootstrap.connect(host, port).sync();
            // 当代客户端链路关闭
            //去掉channelFuture.channel().closeFuture().sync();
            channelFuture.channel().closeFuture();
            countDownLatch.await();
            return clientHandler.getResponse();
        } finally {
            // 优雅退出，释放NIO线程组
            eventLoopGroup.shutdownGracefully();

        }

    }
}
